// Copyright Epic Games, Inc. All Rights Reserved.

#pragma once

#include "Camera/CameraComponent.h"
#include "GameFramework/Actor.h"

#include "LyraCameraComponent.generated.h"

class UCanvas;
class ULyraCameraMode;
class ULyraCameraModeStack;
class UObject;
struct FFrame;
struct FGameplayTag;
struct FMinimalViewInfo;
template <class TClass> class TSubclassOf;

DECLARE_DELEGATE_RetVal(TSubclassOf<ULyraCameraMode>, FLyraCameraModeDelegate);


/**
 * ULyraCameraComponent
 *
 *	该项目使用的基础相机组件类。
 */
UCLASS()
class ULyraCameraComponent : public UCameraComponent
{
	GENERATED_BODY()

public:

	ULyraCameraComponent(const FObjectInitializer& ObjectInitializer);

	// 如果指定Actor上存在相机组件，则返回该相机组件。
	UFUNCTION(BlueprintPure, Category = "Lyra|Camera")
	static ULyraCameraComponent* FindCameraComponent(const AActor* Actor) { return (Actor ? Actor->FindComponentByClass<ULyraCameraComponent>() : nullptr); }

	// 返回相机正在观察的目标Actor。
	virtual AActor* GetTargetActor() const { return GetOwner(); }

	// 用于查询最佳相机模式的委托。
	FLyraCameraModeDelegate DetermineCameraModeDelegate;

	// 向视野字段添加偏移。该偏移仅持续一帧，应用后会被清除。
	void AddFieldOfViewOffset(float FovOffset) { FieldOfViewOffset += FovOffset; }

	virtual void DrawDebug(UCanvas* Canvas) const;

	// 获取与顶层关联的标签及其混合权重
	void GetBlendInfo(float& OutWeightOfTopLayer, FGameplayTag& OutTagOfTopLayer) const;

protected:

	virtual void OnRegister() override;
	virtual void GetCameraView(float DeltaTime, FMinimalViewInfo& DesiredView) override;

	virtual void UpdateCameraModes();

protected:

	// 用于混合相机模式的堆栈。
	UPROPERTY()
	TObjectPtr<ULyraCameraModeStack> CameraModeStack;

	// 应用于视野字段的偏移。该偏移仅持续一帧，应用后会被清除。
	float FieldOfViewOffset;

};